﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace TheLogWatcher
{
    public partial class MainWindow : Form
    {
        private void backgroundFileIndexer_DoWork(object sender, DoWorkEventArgs e)
        {
            LogFile logfile = (LogFile)e.Argument;
            if (logfile == null || logfile.Logformat == null)
            {
                return;
            }

            FileStream fileStream = new FileStream(logfile.Filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            {
                if (fileStream == null || fileStream.Length == 0)
                {
                    return;
                }
                DateTime startTime = DateTime.Now;
                long pieceSize = fileStream.Length / 100;

                // Jump to position after last known entry
                long lineStart = logfile.LastKnownPosition;
                fileStream.Position = lineStart;
                long piecesDone = 0;

                StringBuilder cache = new StringBuilder();
                int bufferSize = 256;
                bool endReached = false;
                byte[] bytes = null;
                Regex regex = new Regex(logfile.Logformat.RegEx, RegexOptions.Multiline);
                while (!endReached)
                {
                    bytes = new byte[bufferSize];

                    // Read a few bytes into buffer
                    int readBytes = fileStream.Read(bytes, 0, bufferSize);
                    if (readBytes < bufferSize)
                    {
                        endReached = true;
                    }
                    cache.Append(Encoding.Default.GetString(bytes));
                    Console.WriteLine("Checking: " + cache.ToString());
                    MatchCollection matchCol = regex.Matches(cache.ToString());
                    if (matchCol == null || matchCol.Count == 0)
                    {
                        Console.WriteLine("RegEx doesn't match.");
                        return;
                    }
                    int lastMatchPos = 0;
                    if (matchCol.Count < 2)
                    {
                        continue;
                    }
                    for (int i = 1; i < matchCol.Count; i++)
                    {
                        Match match = matchCol[i];
                        GroupCollection groups = match.Groups;
                        string type = groups["Type"].Value;
                        if (type == null)
                        {
                            Console.WriteLine("Type cannot be recognized.");
                            continue;
                        }

                        string date = groups["Date"].Value;
                        string time = groups["Time"].Value;

                        // Add current log entry line number to list
                        long streamOffset = lineStart + match.Index;
                        MessageTypes currentType = MessageType.GetMessageType(type);
                        IndexObject iObj = new IndexObject();
                        iObj.FileIndex = streamOffset;
                        iObj.MessageType = currentType;
                        this.dataAccess.addIndex(iObj);
                        RedrawListView();

                        // Set next line start delimiter
                        lastMatchPos = match.Index + match.Length;

                        if ((fileStream.Position + bufferSize) > fileStream.Length)
                        {
                            endReached = true;
                            break;
                        }
                    }
                    lineStart += lastMatchPos;

                    // Remove already found matches from buffer
                    cache.Remove(0, lastMatchPos);

                    //fileStream.Position = lineStart;
                    if (fileStream.Position > piecesDone)
                    {
                        piecesDone += pieceSize;
                    }
                }
            }
        }

        private void backgroundFileIndexer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}
